/*:
* @plugindesc Town Portal Scroll
* @author cnda2010
* @version 1.0.0
* @date 3/3/2019
*
* @param Town Portal Animation1
* @type animation
* @desc 开始传送动画
* @default 117
*
* @param Town Portal Animation2
* @type animation
* @desc 结束传送动画
* @default 120
*
* @param Town Portal Timeout
* @type number
* @min 0
* @desc 留给传送动画的播放时间【单位：毫秒】，根据开始动画的长度设定为佳。 默认值：2000
* @default 2000
*
* @param Town Portal Fade Type
* @type select
* @option 变黑
* @value 0
* @option 变白
* @value 1
* @option 无
* @value 2
* @desc 传送时的淡入淡出模式
* @default 0
*
* @help
* 回城道具技能定义，使用说明如下
* 1. 设置参数
* （1）前两个参数为回城开始和结束时播放的动画
* （2）第三个参数为传送延时【单位：毫秒】，此段时间用于播放起始动画，请
* 根据传送起始动画长度适量调节
* （3）第四个参数为淡入淡出模式
*
* 2. 地图数据定义
* 以下标签用于地图备注中
* <Town Portal Location: mapId, x, y> 必须严格按照此格式书写，保留空格
* 在此地图使用回城，会传送至指定地图的指定坐标处，若地图没有这个标签或
* 数据配置有误，回城道具技能在此地图下将被禁用
* 
* <Town Portal Direction: dir>
* 指定回城完毕后人物的朝向，方向取值【up down left right】不区分大小写
* 若不指定该标签，人物朝向不变
*
* 3. 回城物品技能定义
* 物品/技能标签
* <Town Portal>
* 此技能/物品用于回城，此时该物品的一切其他功能均失效
*
* 4. 存档控制
* 以下标签用于控制传送后是否存档
* <Save After Town Portal: canSave> 取值ON/OFF
*
* 5. 回城条件控制
* 以下的插件命令用于控制回城道具技能的使用条件
* 默认情况下，回城是允许使用的，但是在某些情况下我们可以用下面的插件命
* 令禁止它
* DisableTownPortal 禁止使用回城
*
* 在禁止回城以后，若要允许使用回城，则用下面的插件命令
* EnableTownPortal 允许使用回城

* 6. SWDA：魔化韩国时，自动切换韩国内场景的目的地地图ID
*/

var TownPortalManager = TownPortalManager || {};
var params = PluginManager.parameters("CD_TownPortal");

TownPortalManager.TOWN_PORTAL_ANIMATION1 = Number(params["Town Portal Animation1"]) || 0;
TownPortalManager.TOWN_PORTAL_ANIMATION2 = Number(params["Town Portal Animation2"]) || 0;
TownPortalManager.TOWN_PORTAL_TIMEOUT = Number(params["Town Portal Timeout"]) || 2000;
TownPortalManager.TOWN_PORTAL_FADE_TYPE = Number(params["Town Portal Fade Type"]) || 0;

TownPortalManager.AFTER_TP_NOTHING = 0;
TownPortalManager.AFTER_TP_CAN_SAVE = 1;
TownPortalManager.AFTER_TP_CANNOT_SAVE = 2;

TownPortalManager.getSaveType = function(typeString){
	var typeStr = typeString.trim().toUpperCase();

	switch(typeStr){
		case "ON":
			return TownPortalManager.AFTER_TP_CAN_SAVE;
		case "OFF":
			return TownPortalManager.AFTER_TP_CANNOT_SAVE;
	}

	return TownPortalManager.AFTER_TP_NOTHING;
};

//修改存档模式
TownPortalManager.changeSaveType = function(){
	switch($dataMap.saveTypeAfterTP){
		case TownPortalManager.AFTER_TP_CAN_SAVE:
			$gameSystem.enableSave();
			break;
		case TownPortalManager.AFTER_TP_CANNOT_SAVE:
			$gameSystem.disableSave();
			break;
	}
};

//方向定义
TownPortalManager.DIRECTION_NONE = 0;
TownPortalManager.DIRECTION_UP = 8;
TownPortalManager.DIRECTION_DOWN = 2;
TownPortalManager.DIRECTION_LEFT = 4;
TownPortalManager.DIRECTION_RIGHT = 6;

TownPortalManager.getDirection = function(dirString){
	var str = dirString.trim().toUpperCase();

	switch(str){
		case "UP":
			return TownPortalManager.DIRECTION_UP;
		case "DOWN":
			return TownPortalManager.DIRECTION_DOWN;
		case "LEFT":
			return TownPortalManager.DIRECTION_LEFT;
		case "RIGHT":
			return TownPortalManager.DIRECTION_RIGHT;
	}

	return TownPortalManager.DIRECTION_NONE;
};

//回城数据类型定义
function TownLocation(mapId, mapX, mapY, direction){
	this.initialize(mapId, mapX, mapY, direction);
};

TownLocation.prototype.initialize = function(mapId, mapX, mapY, direction){
	this._mapId = mapId;
	this._mapX = mapX;
	this._mapY = mapY;
	this._dir = direction;
};

TownLocation.prototype.mapId = function(){
	return this._mapId;
};

TownLocation.prototype.mapX = function(){
	return this._mapX;
};

TownLocation.prototype.mapY = function(){
	return this._mapY;
};

TownLocation.prototype.direction = function(){
	return this._dir;
};

//Data数值封装
TownPortalManager.IS_MAP_LOADED = DataManager.isMapLoaded;
DataManager.isMapLoaded = function() {
    var loaded = TownPortalManager.IS_MAP_LOADED.call(this);
    if(!loaded)
		return loaded;

    TownPortalManager.loadTownPortalData();

    return loaded;
};

TownPortalManager.loadTownPortalData = function(){
	var map = $dataMap;
	if(!map)
		return;
	if($testEvent)
		return;

	var saveType = map.meta["Save After Town Portal"];
	map.saveTypeAfterTP = TownPortalManager.AFTER_TP_NOTHING;
	if(saveType)
		map.saveTypeAfterTP = TownPortalManager.getSaveType(saveType);

	map.townPortalLocation = null;
	if(!map.meta["Town Portal Location"])
		return;

	var reg = /<Town Portal Location: (\d*), (\d*), (\d*)>/;
	reg.exec(map.note);

	var mapId = Number(RegExp.$1) || 0;
	var mapX = Number(RegExp.$2) || 0;
	var mapY = Number(RegExp.$3) || 0;
	var dir = TownPortalManager.DIRECTION_NONE;
	if(map.meta["Town Portal Direction"]){
		var dirString = map.meta["Town Portal Direction"];
		dir = TownPortalManager.getDirection(dirString);
	}

	if(mapId !== 0)
		map.townPortalLocation = new TownLocation(mapId, mapX, mapY, dir);
};

//道具技能设定部分
//1. 判定是否为传送
DataManager.isTownPortal = function(item){
	if(!item)
		return false;

	if(item.meta["Town Portal"])
		return true;
	else
		return false;
};

//2. 处理使用
TownPortalManager.DETERMINE_ITEM = Scene_ItemBase.prototype.determineItem;
Scene_ItemBase.prototype.determineItem = function() {
    if(DataManager.isTownPortal(this.item()))
    	this.startTownPortal();
    else
    	TownPortalManager.DETERMINE_ITEM.call(this);
};

//3. 内部处理函数，执行传送
Scene_ItemBase.prototype.startTownPortal = function(){
	var townPortalLocation = $dataMap.townPortalLocation;
	if(!townPortalLocation)
		return;

	this.payTownPortalCost();
	$gamePlayer.startTownPortal();
	this.executeTownPortal();
};

//3.1 执行消耗
Scene_ItemBase.prototype.payTownPortalCost = function(){
	var user = this.user();
	var item = this.item();
	if(DataManager.isItem(item)){
		SoundManager.playUseItem();
		user.consumeItem(item);
	}

	if(DataManager.isSkill(item)){
		SoundManager.playUseSkill();
		user.paySkillCost(item);
	}
};

//3.2 执行传送
Scene_ItemBase.prototype.executeTownPortal = function(){
	//3.2.1 播放动画
	SceneManager.goto(Scene_Map);
	$gamePlayer.gatherFollowers();
	TownPortalManager.playStartTownPortalAnimation();

	//3.2.2 检验保存
	TownPortalManager.changeSaveType();

	//3.2.3 传送开始	
	setTimeout(function(townPortalLocation){
		var mapId = townPortalLocation.mapId();
		if ($gameSwitches.value(212) && mapId == 131)   //魔化韩国
			mapId = 158;
		var x = townPortalLocation.mapX();
		var y = townPortalLocation.mapY();
		var dir = townPortalLocation.direction();
		$gamePlayer.reserveTransfer(mapId, x, y, dir, TownPortalManager.TOWN_PORTAL_FADE_TYPE);
	}, TownPortalManager.TOWN_PORTAL_TIMEOUT, $dataMap.townPortalLocation);
};

//4. 处理事后
//4.1 玩家封装一个标记，确定是否为回城传送
TownPortalManager.INIT_PLAYER = Game_Player.prototype.initialize;
Game_Player.prototype.initialize = function() {
    TownPortalManager.INIT_PLAYER.call(this);

    this._townPortal = false;//封装使用回城标记，隶属于【4.1】
    this._enableTownPortal = true;//允许传送的标记，隶属于【5.1】
};

Game_Player.prototype.isTownPortal = function(){
	return this._townPortal;
};

Game_Player.prototype.startTownPortal = function(){
	this._townPortal = true;
};

Game_Player.prototype.endTownPortal = function(){
	this._townPortal = false;
};

//4.2 执行传送后动画
TownPortalManager.PERFORM_TRANSFER = Game_Player.prototype.performTransfer;
Game_Player.prototype.performTransfer = function() {
    TownPortalManager.PERFORM_TRANSFER.call(this);

    if(this.isTownPortal()){
    	TownPortalManager.playEndTownPortalAnimation();
    	setTimeout(function(player){
    		player.endTownPortal();
    	}, TownPortalManager.TOWN_PORTAL_TIMEOUT, this);
    }
};

TownPortalManager.playStartTownPortalAnimation = function(){
	$gamePlayer._animationId = TownPortalManager.TOWN_PORTAL_ANIMATION1;
};

TownPortalManager.playEndTownPortalAnimation = function(){
	$gamePlayer._animationId = TownPortalManager.TOWN_PORTAL_ANIMATION2;
};

//5. 回城技能道具使用条件以及禁止回城模式
//5.1 禁止传送模式标记
Game_Player.prototype.canTownPortal = function(){
	return this._enableTownPortal;
};

Game_Player.prototype.enableTownPortal = function(){
	this._enableTownPortal = true;
};

Game_Player.prototype.disableTownPortal = function(){
	this._enableTownPortal = false;
};

//5.2 技能物品使用条件
TownPortalManager.TOWN_PORTAL_CAN_USE = Game_BattlerBase.prototype.canUse;
Game_BattlerBase.prototype.canUse = function(item) {
    var canUse = TownPortalManager.TOWN_PORTAL_CAN_USE.call(this, item);
    if(DataManager.isTownPortal(item)){
    	if(!TownPortalManager.mapCanTownPortal())//地图禁止回城
    		canUse = false;
    	if(!$gamePlayer.canTownPortal())//事件禁止回城
    		canUse = false;
    	if($gameParty.inBattle())//战斗中禁止回城
    		canUse = false;
    }

    return canUse;
};

//5.2.1 地图传送条件：没有指定回城坐标或者无效坐标的地图禁止传送
TownPortalManager.mapCanTownPortal = function(){
	if(!$dataMap)
		return false;
	
	var location = $dataMap.townPortalLocation;
	if(!location)
		return false;

	if(location.mapId() <= 0)
		return false;

	if(location.mapX() < 0 || location.mapY() < 0)
		return false;

	return true;
};

//5.2.2 禁止传送状态指定：插件命令EnableTownPortal与DisableTownPortal
TownPortalManager.PLUGIN_COMMAND = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
	TownPortalManager.PLUGIN_COMMAND.call(this, command, args);

	if(command == 'EnableTownPortal')
		$gamePlayer.enableTownPortal();
	if(command == 'DisableTownPortal')
		$gamePlayer.disableTownPortal();
};

//6. 移动控制：为了防止在传送过程中因移动触发事件而导致不可预知的BUG，传送过程中禁止移动
//6.1 禁止玩家移动
TownPortalManager.PLAYER_CAN_MOVE = Game_Player.prototype.canMove;
Game_Player.prototype.canMove = function() {
    var canMove = TownPortalManager.PLAYER_CAN_MOVE.call(this);

    if($gamePlayer.isTownPortal())
    	canMove = false;

    return canMove;
};

//6.2 禁止事件移动
TownPortalManager.UPDATE_EVENT_MOVEMENT	= Game_Event.prototype.updateSelfMovement;
Game_Event.prototype.updateSelfMovement = function() {
    if(!$gamePlayer.isTownPortal())
    	TownPortalManager.UPDATE_EVENT_MOVEMENT.call(this);
};
